home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 11243 / 11243.xpi / chrome / skipscreen.jar / content / searchRefinement.js < prev    next >
Text File  |  2009-11-10  |  10KB  |  258 lines

  1. //1. This javascript code runs in the Firefox chrome level. On
  2. //DomContentLoaded, it will determine if the current page is a Google,
  3. //Yahoo or Bing search results page. If so, it fires off an ajax
  4. //request and puts the refinement links at the top of the page.
  5.  
  6. // 2. The code does nothing if a div with id ==
  7. // "scTopOfPageRefinementLinks" already exists on the page. This way,
  8. // if the user has more than one extension that tries to add
  9. // refinement links to the page, the first extension to activate is
  10. // the one that displays the links, and the other extensions don't.
  11.  
  12. // 3. The partner object (on line 3 of the javascript code) has a
  13. // property called "uiLabel", which is the text that is used to label
  14. // the refinements in the UI. Feel free to change that label, or make
  15. // any other UI tweaks, so long as the enclosing div still has id ==
  16. // "scTopOfPageRefinementLinks".
  17.  
  18. // 4. The code creates one new window-level variable, called
  19. // window.scRefinementQuery.
  20.  
  21.  
  22. (function () {
  23.  
  24.     function refinementsEnabled() {
  25.  
  26.     var startPoint="extensions.skipscreen.";
  27.     var pref=Components.classes["@mozilla.org/preferences-service;1"].
  28.       getService(Components.interfaces.nsIPrefService).
  29.         getBranch(startPoint);
  30.     var enabled = pref.getBoolPref("searchrefinementsactive");
  31.     return enabled;
  32.  
  33.     }
  34.  
  35.     function addRefinementLinks() {
  36.  
  37.     var partner = { uiLabel: 'SkipScreen Refinements', partnerCode: 'skipscreen', authCode: 'hgv27565' };
  38.  
  39.     // quit if SC or any other extension has already put the refinement links on the page
  40.     if (_content.document.getElementById('scTopOfPageRefinementLinks')) {
  41.         return;
  42.     }
  43.  
  44.     if ( !refinementsEnabled() ) {return;}
  45.  
  46.     try {
  47.         if (! _content.document.location) {return; }
  48.         var host = _content.document.location.host;
  49.         var pathname = _content.document.location.pathname;
  50.         if (host) {
  51.         var div, insertPoint;
  52.         if (containsSubstring(host, '.google.') && containsSubstring(host,'www') && ((pathname == '/') || (pathname == '/search'))) {
  53.             window.scRefinementQuery = null;
  54.             waitForGoogleAjaxToComplete(partner);
  55.         } else if (containsSubstring(host, 'search.yahoo.')) {
  56.             window.scRefinementQuery = _content.document.getElementById("yschsp").value;
  57.             div = _content.document.getElementById('web');
  58.             insertPoint = getDescendents(div, "ol")[0];
  59.             launchSCAjaxRequestForRefinementLinks(partner, insertPoint, '');
  60.         } else if (containsSubstring(host, '.bing.com') && (pathname == '/search')) {
  61.             window.scRefinementQuery = _content.document.getElementById("sb_form_q").value;
  62.             div = _content.document.getElementById('results');
  63.             insertPoint = getDescendents(div, "ul")[0];
  64.             launchSCAjaxRequestForRefinementLinks(partner, insertPoint, '');
  65.         }
  66.         }
  67.     } catch (ex) {
  68.         // executes on empty tabs, and throws errors....
  69.         // alert("Refinements error: " + ex);
  70.     }
  71.     }
  72.  
  73.     function waitForGoogleAjaxToComplete(partner) {
  74.     if (!window.scRefinementQuery) {
  75.         var aTags = _content.document.getElementsByTagName('a');
  76.         for (var i = 0; (i < aTags.length) && !window.scRefinementQuery; i++) {
  77.         var aTag = aTags[i];
  78.         var href = aTag.href;
  79.         if (containsSubstring(href, '.google.') && (containsSubstring(href, '/advanced_search?q=') || containsSubstring(href, '/swr?q='))) {
  80.             window.scRefinementQuery = href.replace(/.*\?q=/, '').replace(/&.*/, '');
  81.         }
  82.         }
  83.  
  84.         if (!window.scRefinementQuery) {
  85.         setTimeout(waitForGoogleAjaxToComplete, 200, partner);
  86.         return;
  87.         }
  88.     }
  89.  
  90.     var liTags = _content.document.getElementsByTagName('li');
  91.     for (i = 0; i < liTags.length; i++) {
  92.         var liTag = liTags[i];
  93.         var cls = liTag.getAttribute('class');
  94.         if (cls && ((cls == 'g') || (cls.indexOf('g ') === 0))) {
  95.         var insertPoint = liTag.parentNode;
  96.         launchSCAjaxRequestForRefinementLinks(partner, insertPoint, '');
  97.         break;
  98.         }
  99.     }
  100.     }
  101.  
  102.     function launchSCAjaxRequestForRefinementLinks(partner, insertPoint, yStyle) {
  103.     if (_content.document.getElementById('scTopOfPageRefinementLinks')) {
  104.         return;
  105.     }
  106.  
  107.     var div = _content.document.createElement("div");
  108.     div.innerHTML = '<div id=scTopOfPageRefinementLinks scTopPos=1 partner="' + partner.partnerCode + '" style="height: 20px; margin-top: 7px; margin-bottom: 7px;' + yStyle + '"></div>';
  109.     insertPoint.parentNode.insertBefore(div, insertPoint);
  110.  
  111.     var url = 'http://' + partner.authCode + '.surfcanyon.com/queryReformulation?partner=' + partner.partnerCode + '&authCode=' + partner.authCode + '&q=' + window.scRefinementQuery.replace(/ /g, '+');
  112.     var xhr = new window.XMLHttpRequest();
  113.     xhr.open("GET", url, true);
  114.     xhr.onreadystatechange = function() {
  115.         if (xhr.readyState == 4) {
  116.         var parser = new window.DOMParser();
  117.         var xmlRoot = parser.parseFromString(xhr.responseText, "text/xml");
  118.         var itemNodes = xmlRoot.getElementsByTagName('refinement');
  119.  
  120.         var items = [];
  121.         var runningLength = 0;
  122.         for (var i = 0; i < itemNodes.length; i++) {
  123.             try {
  124.             var itemNode = itemNodes[i];
  125.             var refinement = itemNode.textContent.toLowerCase();
  126.             var refinementLength = refinement.length;
  127.             if (runningLength + refinementLength < 80) {
  128.                 runningLength += refinementLength;
  129.                 var query = makeRefinementQuery(refinement).replace(/ /g, '+');
  130.                 items.push('<a href="http://search.surfcanyon.com/search?f=nrl' + i + '&q=' + query + '&partner=' + partner.partnerCode + '">' + refinement + '</a>');
  131.             }
  132.             } catch (e) {
  133.             }
  134.         }
  135.  
  136.         if (items.length > 0) {
  137.             var div = _content.document.getElementById('scTopOfPageRefinementLinks');
  138.             if (div && (div.getAttribute('partner') == partner.partnerCode)) {
  139. //                         div.innerHTML = '<font size=-1><b>' + items.join('  ') + '</b>  '
  140. //                 + '<style>#apRefinementDesc:hover    {text-decoration:underline;}\n#apRefinementDesc    {text-decoration:none;}</style> '
  141. //                 + '<span style="color:green" title="help support SkipScreen development — visit our partner">' + partner.uiLabel + '</span>'
  142. //                 + ' <a id="disableRefinement" class="disableRefinement" href="#" title="Disable SkipScreen Refinements">[x]</a></font>';
  143.  
  144.             // TODO: poor styling code....
  145.             div.innerHTML = '<font size=-1><b>' + items.join('  ') + '</b>  '
  146.                 + '<span style="color:green" title="help support SkipScreen development — visit our partner">' + partner.uiLabel + '</span>'
  147.                 + ' <a id="disableRefinement" class="disableRefinement" href="#" title="Disable SkipScreen Refinements" style="text-decoration:none; color:green;">[x]</a></font>';
  148.  
  149.             var killer = _content.document.getElementById('disableRefinement');
  150.             killer.addEventListener('click', disableRefinement, false);
  151.  
  152.             }
  153.         }
  154.         }
  155.     };
  156.     xhr.send(null);
  157.     }
  158.  
  159.     var disableRefinement = function(event)
  160.     {
  161.     event.preventDefault();
  162.         if (confirm("Remove SkipScreen Refinement links?\n(You can re-enable them later in the options menu.)"))
  163.         {
  164.         // from autopager-refinements, as suggested by Surf Canyon
  165.         var evaluate = function(node,expr,max)
  166.         {
  167.         var doc = (node.ownerDocument == null) ? node : node.ownerDocument;
  168.         var found = [];
  169.         try{
  170.             var xpe = new XPathEvaluator();
  171.             var nsResolver = xpe.createNSResolver(doc.documentElement);
  172.             var result = xpe.evaluate(expr, node, nsResolver, 0, null);
  173.  
  174.             var res;
  175.             while ((res = result.iterateNext()) && (typeof(max)=='undefined' || found.length<max))
  176.             found.push(res);
  177.         }catch(e) {}
  178.         return found;
  179.         };
  180.  
  181.         var startPoint="extensions.skipscreen.";
  182.         var pref=Components.classes["@mozilla.org/preferences-service;1"].
  183.           getService(Components.interfaces.nsIPrefService). getBranch(startPoint);
  184.         pref.setBoolPref("searchrefinementsactive",false);
  185.         var rmv = evaluate(event.target.ownerDocument,"//div[@id='scTopOfPageRefinementLinks']",1);
  186.         for(var i=0;i<rmv.length;i++){
  187.         rmv[i].parentNode.removeChild(rmv[i]);
  188.         }
  189.         }
  190.     };
  191.  
  192.     function listenOndisableRefinement(doc) {
  193.         if (!doc.getElementById('scTopOfPageRefinementLinks')) {
  194.             return;
  195.         }
  196.     var links = doc.evaluate("//a[@id='disableRefinement' and not(@class='disableRefinementListented')]",
  197.                  doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  198.         for(var i=0;i<links.length;i++)
  199.         {
  200.             links[i].addEventListener("click", disableRefinement, true);
  201.             links[i].setAttribute("class", "disableRefinementListented");
  202.         }
  203.  
  204.     }
  205.  
  206.  
  207.     function getDescendents(node, tagName) {
  208.     var arr = [];
  209.     if (node && node.childNodes) {
  210.         var childNodes = node.childNodes;
  211.         for (var i = 0; i < childNodes.length; i++) {
  212.         var child = childNodes.item(i);
  213.         if (child.tagName && (!tagName || (child.tagName.toUpperCase() == tagName.toUpperCase()))) {
  214.             arr[arr.length] = child;
  215.         }
  216.         if (child.hasChildNodes()) {
  217.             arr = arr.concat(getDescendents(child, tagName));
  218.         }
  219.         }
  220.     }
  221.     return arr;
  222.     }
  223.  
  224.     function containsSubstring(text, substring) {
  225.     return text && substring && (text.indexOf(substring) >= 0);
  226.     }
  227.  
  228.     function loadHandler() {
  229.     var appcontent = document.getElementById("appcontent");
  230.     if (appcontent) {
  231.         appcontent.addEventListener("DOMContentLoaded", addRefinementLinks, false);
  232.     }
  233.     window.removeEventListener("load", loadHandler, false);
  234.     }
  235.  
  236.     function unloadHandler(event) {
  237.     window.removeEventListener("unload", unloadHandler, false);
  238.     }
  239.  
  240.     // regex in the replace statement befuddles the indenting parser in tested hs-modes
  241.    function makeRefinementQuery(refinement) {
  242.      var query = refinement;
  243.      var words = window.scRefinementQuery.replace(/"'\(\),/g, '').replace(/\+/g, ' ').split(' ');
  244.  
  245.      for (var i = 0; i < words.length; i++) {
  246.        var word = words[i];
  247.        if (!containsSubstring(query.toLowerCase(), word.toLowerCase())) {
  248.      query = query + ' ' + word;
  249.        }
  250.      }
  251.  
  252.      return query;
  253.    }
  254.  
  255.  
  256.    window.addEventListener("load", loadHandler, false);
  257.    window.addEventListener("unload", unloadHandler, false);
  258.  })();